/**
 * @Author: 陈瑞鹏
 * @Date:   2022-12-14 10:42:08
 * @Last Modified by:   陈瑞鹏
 * @Last Modified time: 2023-09-25 09:16:01
 */
import abiao_utils from "abiao_utils";
import utils from "../utils/utils";
import Barrack from "./barrack.model";
import Email from "./email.model";
import Exchange from "./exchange.model";
import GUser from "./gUser.model";
import Treasure from "./treasure.model";
import GDailyTask from "./gDailyTask.model";
import Redis from "../utils/redis";
import Retain from "../models/stats/retain.model";

/**
 * @Author: 陈瑞鹏
 * @Date:   2022-12-14 10:42:08
 * @Last Modified by:   陈瑞鹏
 * @Last Modified time: 2023-01-10 16:50:16
 */
export default class guard {

  static async barrackInit(roleId) {
    let barrackData: any = await utils.get_all_json("guard/hero.json");
    for (const interator of barrackData) {
      let barrackRes: any = await Barrack.findOne({ roleId, id: interator.id });
      let bool = Number(interator.id) < 7 ? false : true;
      if (!barrackRes) {
        let info = {
          roleId,
          id: interator.id,
          lock: bool,
          updateTime: abiao_utils.date(1),
          createTime: abiao_utils.date(1),
        }
        await Barrack.create(info);
      }
    }
  }

  static async sendProp(roleId, rewardArr) {
    // let rewardArr = JSON.parse(victoryD.rewardArr);
    // console.log(rewardArr);
    let arr = [];
    await rewardArr.forEach(async element => {
      if (element) {
        switch (element['type']) {
          case "1":
            let num = abiao_utils.getRandom(Number(element['min']), Number(element['max']));
            arr.push({ type: 1, num, id: 0 })
            break;
          case "2":
            let id = abiao_utils.getRandom(1, 6);
            arr.push({ type: 2, num: element['num'], id })
            break;
          case "3":
            id = abiao_utils.getRandom(7, 9);
            arr.push({ type: 2, num: element['num'], id })
            break;
          case "4":
            id = abiao_utils.getRandom(10, 12);
            arr.push({ type: 2, num: element['num'], id })
            break;
          case "5":
            id = abiao_utils.getRandom(13, 18);
            arr.push({ type: 2, num: element['num'], id })
            break;
          case "6":
            arr.push({ type: 3, num: 1, id: element['num'] });
            break;
        }
      }
    });

    await arr.forEach(async (ele) => {
      if (ele) {
        if (ele.type == 1) {
          let userRes = await GUser.findOne({ roleId });
          await GUser.updateOne({ roleId }, { diamonds: userRes['diamonds'] + ele.num, updateTime: abiao_utils.date() });
        } else if (ele.type == 2) {
          let bRes = await Barrack.findOne({ roleId, id: ele.id });
          await Barrack.updateOne({ roleId, id: ele.id }, { fragment: Number(bRes['fragment']) + Number(ele.num), updateTime: abiao_utils.date() });
        } else if (ele.type == 3) {
          let treasureRes = await Treasure.find({ roleId }).lt("step", 4);
          let len = 0;
          treasureRes.forEach(ele => {
            if (ele['step'] < 4) {
              len++;
            }
          })

          if (len < 4) {
            //创建宝箱
            let step = (Number(ele.num) == 1) ? 3 : 1;
            let info = {
              treasureId: Number(ele.num),
              roleId,
              step: step,
              openTime: 0,
              updateTime: abiao_utils.date(1),
              createTime: abiao_utils.date(1),
            }
            await Treasure.create(info);
          }
        }
      }
    });

    return arr;
  }

  /**
   * 
   * @param roleId 
   * @param sendType  1 为 个人 2为全体
   * @param type  1 为邮件 2为通知
   * @param title 
   * @param desc 
   * @param rewardArr 
   */
  static async sendEmail(roleId, sendType, type, title, desc, rewardArr) {
    let info = {
      roleId,
      type,
      title,
      desc,
      rewardArr,
      isRecive: false,
      updateTime: abiao_utils.date(1),
      createTime: abiao_utils.date(1),
    }
    //发送给个人
    if (sendType == 1) {
      await Email.create(info);
    } else if (sendType == 2) {
      let allUser = await GUser.find({ status: true });
      allUser.forEach((ele) => {
        info.roleId = ele['roleId'];
        Email.create(info);
      })
    }
  }

  /**
   * 创建兑换码
   * @param id 
   * @param type 1 全体 2 个人只能领一次，领过失效
   * @param rewardArr 
   */
  static async sendExchange(id, type, rewardArr, title, desc) {
    let info = {
      id,
      title,
      desc,
      type,
      rewardArr,
      isUse: false,
      updateTime: abiao_utils.date(1),
      createTime: abiao_utils.date(1),
    }
    Exchange.create(info);
  }

  /**
   * 初始化任务表
   * @param roleId 
   */
  static async dailyTaskInit(roleId) {
    const json: any = await utils.get_all_json("guard/renwubiao.json");

    for (const interator of json) {
      let taskRes: any = await GDailyTask.findOne({ roleId, id: interator.gradeID });
      if (!taskRes) {
        let info = {
          roleId,
          id: interator.gradeID,
          target: interator.Conditions,
          progress: 0,
          updateTime: abiao_utils.date(2),
          createTime: abiao_utils.date(1),
        }
        await GDailyTask.create(info);
      } else {
        let nowDate = abiao_utils.date(2);
        if (taskRes.updateTime != nowDate) {
          await GDailyTask.updateOne({ roleId, id: interator.gradeID }, { progress: 0, updateTime: nowDate, isRecive: false });
        }
      }
    }
  }

  /**
   * 获取排行榜数据 并存入redis
   * @param condition 查询条件
   * @param sortObj 排序规则
   * @param roleId 用户id
   * @param redisStr redis 保存前缀
   */
  static async getRankData(condition: any, sortObj: any, roleId: any, redisStr: any) {

    let list = await GUser.find(condition).sort(sortObj);

    let groupedData = await utils.groupData(list, 50);

    let rankData = [];

    for (let i: number = 0; i < groupedData.length; i++) {

      let group = groupedData[i];

      for (let j: number = 0; j < group.length; j++) {

        let entry = group[j];

        entry.rank = j + 1;

        entry.worldId = i + 1;

        await Redis.set(redisStr + ":rank:" + entry.roleId, entry.worldId);
      }

      if (!rankData[i + 1]) {
        rankData[i + 1] = [];
      }

      rankData[i + 1] = group;
    }

    if (rankData && rankData.length > 0) {

      await Redis.set(redisStr + ":rank", JSON.stringify(rankData), 15 * 60);

    }

    return rankData;

  }
}